/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "MBT_Engine.h"
#include <node后端.h>
#include <节点数据声明.h>
#include <节点编辑.h>
#include <Context/数据创建销毁.h>
#include <matXX.h>

#include <atomic>



#define DEF_视口手柄元素网格_轴线_移动 0
#define DEF_视口手柄元素网格_箭头X_移动 1
#define DEF_视口手柄元素网格_箭头Y_移动 2
#define DEF_视口手柄元素网格_箭头Z_移动 3

#define DEF_视口手柄元素网格_万向_旋转 4
#define DEF_视口手柄元素网格_线圈X_旋转 5
#define DEF_视口手柄元素网格_线圈Y_旋转 6
#define DEF_视口手柄元素网格_线圈Z_旋转 7

#define DEF_视口手柄元素网格_x轴线 8
#define DEF_视口手柄元素网格_y轴线 9
#define DEF_视口手柄元素网格_z轴线 10

#define DEF_视口手柄元素总数量 11

#define DEF_输入插座标题 (L"输入插座")
#define DEF_输出插座标题 (L"输出插座")

enum E_物体数据类型 {
	e_模型,
	e_八叉树,
	e_射线拾取点,
	e_范围拾取点,
	e_射线拾取八叉树,
	e_范围拾取八叉树,
	//e_材质节点树,
	e_节点视口链接节点树,
	E_线,
};




typedef struct {
	C_节点基类*		node;
	E_节点更新方式	更新方式;
}S_编辑物体更新节点;


typedef struct {
	std::string m_Path;
	E_节点更新方式	更新方式;
}S_库节点加载;


struct S_界面框架构建 {
	S_界面框架构建();
	virtual void f_保存界面框架(FILE* f) = 0;
	virtual void f_加载界面框架(FILE* f) = 0;
	virtual void f_构建默认界面(FILE* f, C_Widget* root) = 0;
};




struct S_框架 {
	static S_Engine engine;
	static S_设备环境 ctx;
	static S_设备 GPU;

	static uint32 版本号[2];
	

	static S_Scene* g_Scene;
	static S_线管* g_索引绘制线管;
	static S_线管* g_线段绘制线管;
	static S_着色* g_单色Shader;
	
	
	
	static S_材质* g_体素BOX材质;
	static S_材质* g_线段绘制材质;
	static S_材质* g_VecSphere材质;
	static S_材质* g_Cube材质;
	static S_材质* g_索引绘制材质;
	//static S_材质* g_选择物体材质;
	//static S_材质* g_描边材质;


	//static S_摄像机*            g_当前操作摄像机;
	static S_物体*              g_基准网格线;
	static S_物体*              g_变换手柄;
	static std::vector<S_物体*> g_变换手柄方向线;
	static std::vector<S_物体*> g_变换手柄圆圈线;
	static std::vector<S_物体*> g_变换手柄轴向线;
	static std::vector<S_物体*> g_变换手柄移动箭头;
	static std::vector<S_物体*> g_变换手柄缩放端点;
	static S_MeshTranformProp          G变换手柄外接圆绘制属性;
	static S_MeshTranformProp          G变换手柄方向线绘制属性;
	static S_MeshTranformProp          G变换手柄端箭头绘制属性[3];
	static S_材质*             g_手柄线材质;
	static S_材质*             g_手柄面材质;
	//static S_物体*		g_旋转变换手柄;
	//static S_物体*		g_缩放变换手柄;
	//static S_摄像机*	g_相机;
	static std::set<S_摄像机*>	g_视口相机;
	
	static S_物体*				g_当前独立显示物体;
	static S_物体*				g_Debug物体;
	
	//static std::vector<S_物体拾取信息>	g_当前物体拾取;
	static E_物体数据类型	g_当前独显物体类型;

	static uint32		g_拾取手柄;
	static bool			g_开启变换;
	static E_变换		g_变换方式;
	static E_轴向		g_变换轴;
	static vec3			g_视线向量;
	static vec2			g_鼠标起始坐标;


	static bool			g_开启节点移动;


	//static S_UI创建环境*	g_UI环境;
	static C_Widget管理*	g_UIGM;
	static S_设备环境*		g_3D视口环境;


	static fp_无参数函数指针	gfu_更新选择节点;




	static vec2 g节点创建初始位置;

	static bool		g_变换开关;
	//static int32           g_渲染帧;
	static bool    g_播放帧;
	
	
	static S_Props	g_变换类型开关;
	static S_Props	g_骨骼姿态编辑模式;
	//static S_Props	m_骨骼编辑模式;
	//static S_Props	m_灯光编辑模式;
	static E_物体类型	g当前编辑对象类型;

	//static S_Props	g_节点树容器;
	//static std::vector<S_MapPtrItem> g_物体节点树;
	static std::vector<S_MapPtrItem> g_材质节点树;


	static std::vector<S_Window*>	g_主窗口;
	static C_Widget*				g_ui文件对话框;
	static S_Window*                g_设置窗口;

	static C_Widget*				g_ui顶层画布;
	static ui_绘制模板_画预设图形*	m_全屏链接线背景绘制;
	static ui_绘制模板_行文本绘制*	m_全屏链接线字符绘制;
	static ui_绘制模板_图标*			m_全屏链接线图标绘制;
	static ui_绘制模板_自定义线*			m_全屏链接线绘制;

	static S_界面框架构建*			g_界面构建;


	static std::string    m_库默认路径;


	S_框架();

	static void	init();
	static void	close();


	static void			f_初始化预设资源(S_设备环境& ctx);
	static S_Window*	f_创建窗口到列队(ivec2 size);
	static void			f_销毁列队窗口();



	//废弃
	//static S_物体*		g_变换手柄_准备替换;
};





struct S_主题颜色 {
	static S_RGBA8UI uic_时间轴时间区;
	static S_RGBA8UI uic_时间网格线;
	static S_RGBA8UI uic_时间轴背景;
	static S_RGBA8UI uic_当前时间线;
	static S_RGBA8UI uic_节点插座文字;
	static S_RGBA8UI uic_节点剪刀线;
	static S_RGBA8UI uic_节点链接线;
	static S_RGBA8UI uic_节点插座;
	static S_RGBA8UI uic_节点面板焦点;
	static S_RGBA8UI uic_节点框;

	static S_RGBA8UI uic_视口手柄X;
	static S_RGBA8UI uic_视口手柄Y;
	static S_RGBA8UI uic_视口手柄Z;

	static S_RGBA8UI uic_选框面颜色;
	static S_RGBA8UI uic_选框边颜色;

	static S_RGBA8UI uic_物体焦点颜色;
	static S_RGBA8UI uic_工作区背景;
	//static std::string uic_节点图标集;

	S_主题颜色();
};

struct S_主题图标 {
	static std::string ico_变换移动;
	static std::string ico_变换旋转;
	static std::string ico_变换缩放;

	S_主题图标();
};



Inline uint64 f_字符串名称转换(int8* str) {
	uint64 字符串构建整数 = 0;
	for (uint8 i = 0; str[i] != '\0'; 字符串构建整数 |= (str[i] << i), ++i) if (i >= 8) break;
	return 字符串构建整数;
}



enum E_工程文件块类型 : uint64 {
	e_工程文件块_文件头 = DEF_字符串拼接ID('p', 'r', 'o', 'p', 's', '\0', '\0', '\0'),

	e_工程文件块_属性变量 = DEF_字符串拼接ID('p', 'r', 'o', 'p', 's', '\0', '\0', '\0'),

	//e_工程文件块_数组F8 = DEF_字符串拼接ID('a', 'r', 'r', 'a', 'y', 'f', '8', '\0'),
	//e_工程文件块_数组F16 = DEF_字符串拼接ID('a', 'r', 'r', 'a', 'y', 'f', '1', '6'),
	//e_工程文件块_数组F32 = DEF_字符串拼接ID('a', 'r', 'r', 'a', 'y', 'f', '3', '2'),
	//e_工程文件块_数组F64 = DEF_字符串拼接ID('a', 'r', 'r', 'a', 'y', 'f', '6', '4'),

	//e_工程文件块_vec2 = DEF_字符串拼接ID('v', 'e', 'c', '2', '\0', '\0', '\0', '\0'),
	//e_工程文件块_vec3 = DEF_字符串拼接ID('v', 'e', 'c', '3', '\0', '\0', '\0', '\0'),
	//e_工程文件块_vec4 = DEF_字符串拼接ID('v', 'e', 'c', '4', '\0', '\0', '\0', '\0'),

	//e_工程文件块_数组vec2 = DEF_字符串拼接ID('v', 'e', 'c', '2', 's', 'z', '\0', '\0'),
	//e_工程文件块_数组vec3 = DEF_字符串拼接ID('v', 'e', 'c', '3', 's', 'z', '\0', '\0'),
	//e_工程文件块_数组vec4 = DEF_字符串拼接ID('v', 'e', 'c', '4', 's', 'z', '\0', '\0'),

	//e_工程文件块_节点树 = DEF_字符串拼接ID('N', 'o', 'd', 'e', 'T', 'r', 'e', 'e'),
	//e_工程文件块_节点 = DEF_字符串拼接ID('N', 'o', 'd', 'e', '\0', '\0', '\0', '\0'),

	e_工程文件块_全局状态   = DEF_字符串拼接ID('q', 'j', 'z', 't', '\0', '\0', '\0', '\0'),
};


struct S_快捷键 {
	static uint8 g_移动快捷键[4];
	static uint8 g_旋转快捷键[4];
	static uint8 g_缩放快捷键[4];

	S_快捷键();
};


struct S_剪切板 {
	S_剪切板();
	~S_剪切板();
	virtual void f_复制() = 0;
	virtual void f_粘贴() = 0;

	static S_剪切板* f_get();
};




Inline void f_global_物体显示模式_打开焦点(S_物体* 物体, uint32 实例ID) {
	switch (物体->m_Type) {
	case E_物体类型::t_多边形:
		f_ob_set颜色2(物体, S_节点UI主题::uic_模型面, 实例ID, 1);
		f_ob_set颜色2(物体, S_节点UI主题::uic_模型线, 实例ID, 2);
		f_ob_set颜色2(物体, S_节点UI主题::uic_模型线, 实例ID, 3);
	case E_物体类型::t_网格:
	case E_物体类型::t_实例:
		
		f_ob_set颜色2(物体, S_节点UI主题::uic_模型焦点, 实例ID, 0);
		if (物体->m_DataNum) {
			//物体->f_打开可视通道(0);
			
		}
		else {
			//if(物体->m_父物体) f_global_物体显示模式_打开焦点(物体->m_父物体, 实例ID);
		}

		break;
	}
	
}
Inline void f_global_物体显示模式_关闭焦点(S_物体* 物体, uint32 实例ID) {
	switch (物体->m_Type) {
	case E_物体类型::t_网格:
	case E_物体类型::t_多边形:
	case E_物体类型::t_实例:
		
		f_ob_set颜色2(物体, {}, 实例ID);
		if (物体->m_DataNum) {
			//物体->f_关闭可视通道(0);
			
		}
		else {
			//if (物体->m_父物体) f_global_物体显示模式_关闭焦点(物体->m_父物体, 实例ID);
		}

		break;
	}
}

void f_global_所在独显模型材质(uint16 模式 = 0xff00);


C_节点基类* f_global_get激活节点后端();
void f_global_clear激活节点();



void f_global_set激活节点(std::vector<C_节点基类*>& nodes);
void f_global_set激活物体(std::vector<C_节点基类*>& nodes);
std::vector<C_节点基类*>&	f_global_get激活节点();
std::vector<C_节点基类*>	f_global_get激活可视物体节点();
vec3						f_global_get激活物体中心点();
uint32						f_global_get选中物体数量();


void                      f_global_set钉住节点(class C_节点面板* panel);
class C_节点面板*         f_global_get钉住节点();

void						f_global_set拾取物体(std::vector<S_物体拾取信息>& obs, bool 清除之前物体 = true);
std::vector<S_物体拾取信息>	f_global_get编辑拾取物体();
void						f_global_clear拾取物体();

void                        f_global_变换手柄到物体中心();

void                        f_frame_bind当前操作物体节点();
std::vector<C_节点基类*>    f_frame_get操作物体节点();


//Inline class C_节点面板* f_global_get节点面板组件(C_节点基类* node) {
//	assert(node->m_UI部件);
//	return (C_节点面板*)(node->m_UI部件);
//}
void						f_global_set切换物体编辑着色类型(S_Props& prop);



void f_global_set全局物体显示();
void f_global_set独立物体显示(C_节点树* node);










